package com.loadburn.heron.shiro;

import com.google.inject.Key;
import com.google.inject.Singleton;
import com.loadburn.heron.config.ResourcesLoader;
import com.loadburn.heron.exceptions.ConvertException;
import com.loadburn.heron.shiro.annotations.ShiroCacheFile;
import com.loadburn.heron.shiro.annotations.ShiroConfigFile;
import com.loadburn.heron.shiro.cache.HeronEhCacheManager;
import com.loadburn.heron.shiro.config.SecurityConfig;
import com.loadburn.heron.shiro.security.CaptchaFormAuthenticationFilter;
import com.loadburn.heron.utils.StringUtils;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.guice.web.ShiroWebModule;

import javax.servlet.ServletContext;
import java.io.IOException;

/**
 * @author slacrey (scstlinfeng@yahoo.com)
 *         Date: 13-12-18
 */
public abstract class HeronShiroWebModule extends ShiroWebModule {

    public final com.google.inject.Key<CaptchaFormAuthenticationFilter> CAPTCHA_AUTHC;
    private static final String CONFIG_FILE = "classpath:security.json";
    private ServletContext servletContext;
    private String configFile;
    protected SecurityConfig securityConfig;

    public HeronShiroWebModule(ServletContext servletContext, String configFile) {
        super(servletContext);
        this.servletContext = servletContext;
        this.configFile = configFile;
        CAPTCHA_AUTHC = Key.get(CaptchaFormAuthenticationFilter.class);

        initSecurityConfig();
    }

    @Override
    protected void configureShiroWeb() {
        bindConstant().annotatedWith(ShiroConfigFile.class).to(configFile);
        if (securityConfig != null) {
            bindConstant().annotatedWith(ShiroCacheFile.class).to(securityConfig.getCacheFile());
        }
        bind(CacheManager.class).to(HeronEhCacheManager.class).in(Singleton.class);

        configureInternal();
        configureSecurityWeb();
    }

    private void initSecurityConfig() {

        ResourcesLoader resourcesLoader = ResourcesLoader.newInstance(this.servletContext);
        String json;
        if (this.configFile != null) {
            json = resourcesLoader.loadConfig(this.configFile);
        } else {
            json = resourcesLoader.loadConfig(CONFIG_FILE);
        }

        try {
            if (!StringUtils.empty(json)) {
                securityConfig = resourcesLoader.convertJsonToObject(json, SecurityConfig.class);
            }
        } catch (IOException e) {
            throw new ConvertException("JSON转换为指定对象出错:" + json, e);
        }

    }

    protected abstract void configureInternal();

    protected abstract void configureSecurityWeb();

}
